﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using SDMX_Common = SDMX_ML.Framework.Common;
using SDMX_Structure = SDMX_ML.Framework.Structure;

namespace SDMX_ML.Framework.Messages
{
    internal class ObjectBuilder
    {
        internal static SDMX_Structure.TextTypeType GetTextTypeType(String type)
        {

            SDMX_Structure.TextTypeType textType = SDMX_Structure.TextTypeType.String;


            switch (type)
            {
                case "String":
                    textType = SDMX_Structure.TextTypeType.String;
                    break;
                case "BigInteger":
                    textType = SDMX_Structure.TextTypeType.BigInteger;
                    break;
                case "Integer":
                    textType = SDMX_Structure.TextTypeType.Integer;
                    break;
                case "Long":
                    textType = SDMX_Structure.TextTypeType.Long;
                    break;
                case "Short":
                    textType = SDMX_Structure.TextTypeType.Short;
                    break;
                case "Decimal":
                    textType = SDMX_Structure.TextTypeType.Decimal;
                    break;
                case "Float":
                    textType = SDMX_Structure.TextTypeType.Float;
                    break;
                case "Double":
                    textType = SDMX_Structure.TextTypeType.Double;
                    break;
                case "Boolean":
                    textType = SDMX_Structure.TextTypeType.Boolean;
                    break;
                case "DateTime":
                    textType = SDMX_Structure.TextTypeType.DateTime;
                    break;
                case "Date":
                    textType = SDMX_Structure.TextTypeType.Date;
                    break;
                case "Time":
                    textType = SDMX_Structure.TextTypeType.Time;
                    break;
                case "Year":
                    textType = SDMX_Structure.TextTypeType.Year;
                    break;
                case "Month":
                    textType = SDMX_Structure.TextTypeType.Month;
                    break;
                case "Day":
                    textType = SDMX_Structure.TextTypeType.Day;
                    break;
                case "MonthDay":
                    textType = SDMX_Structure.TextTypeType.MonthDay;
                    break;
                case "YearMonth":
                    textType = SDMX_Structure.TextTypeType.YearMonth;
                    break;
                case "Duration":
                    textType = SDMX_Structure.TextTypeType.Duration;
                    break;
                case "URI":
                    textType = SDMX_Structure.TextTypeType.URI;
                    break;
                case "Timespan":
                    textType = SDMX_Structure.TextTypeType.Timespan;
                    break;
                case "Count":
                    textType = SDMX_Structure.TextTypeType.Count;
                    break;
                case "InclusiveValueRange":
                    textType = SDMX_Structure.TextTypeType.InclusiveValueRange;
                    break;
                case "ExclusiveValueRange":
                    textType = SDMX_Structure.TextTypeType.ExclusiveValueRange;
                    break;
                case "Incremental":
                    textType = SDMX_Structure.TextTypeType.Incremental;
                    break;
                case "ObservationalTimePeriod":
                    textType = SDMX_Structure.TextTypeType.ObservationalTimePeriod;
                    break;


            }

            return textType;
        }

        internal static SDMX_Common.TextType GetTextType(XElement xmlElement)
        {
            SDMX_Common.TextType textType = null; 

            if (xmlElement.Value != null)
            {
                textType = new SDMX_Common.TextType(xmlElement.Value);

                if (xmlElement.Attribute(XNamespace.Xml + "lang") != null)
                {
                    if (xmlElement.Attribute(XNamespace.Xml + "lang").Value != null)
                    {
                        textType.Lang = xmlElement.Attribute(XNamespace.Xml + "lang").Value;
                    }
                }
            }

            return textType;
        }

        internal static List<SDMX_Common.AnnotationsType> GetAnnotations(XElement enAnnotations, XNamespace ns)
        {
            List<SDMX_Common.AnnotationsType> annotations = new List<SDMX_Common.AnnotationsType>();

            foreach (XElement enAnnotation in enAnnotations.Elements("Annotations"))
            {
                annotations.Add(ObjectBuilder.GetAnnotationsType(enAnnotation));
            }

            return annotations;
        }

        internal static SDMX_Common.AnnotationsType GetAnnotationsType(XElement enAnnotationsType)
        {
            SDMX_Common.AnnotationsType annsType = new SDMX_Common.AnnotationsType();

            foreach (XElement enAnnotation in enAnnotationsType.Elements(Namespaces.GetNS("common") + "Annotation"))
            {
                annsType.Annotation.Add(ObjectBuilder.GetAnnotationType(enAnnotation));
            }

            return annsType;
        }

        internal static SDMX_Common.AnnotationType GetAnnotationType(XElement enAnnotation)
        {
            SDMX_Common.AnnotationType annotationType = new SDMX_Common.AnnotationType();

            XElement title = enAnnotation.Element(Namespaces.GetNS("common") + "AnnotationTitle");

            if (title != null)
            {
                if (title.Value != null)
                {
                    annotationType.AnnotationTitle = title.Value;
                }
            }

            XElement type = enAnnotation.Element(Namespaces.GetNS("common") + "AnnotationType");

            if (type != null)
            {
                if (type.Value != null)
                {
                    annotationType.Annotationtype = type.Value;
                }
            }

            XElement annotationurl = enAnnotation.Element(Namespaces.GetNS("common") + "AnnotationURL");

            if (annotationurl != null)
            {
                if (annotationurl.Value != null)
                {
                    annotationType.AnnotationUrl = annotationurl.Value;
                }
            }

            IEnumerable<XElement> annotationsText = enAnnotation.Elements(Namespaces.GetNS("common") + "AnnotationText");

            if (annotationsText != null)
            {
                foreach (XElement text in annotationsText)
                {
                    annotationType.AnnotationText.Add(GetTextType(text));
                }
            }

            return annotationType;
        }

        internal static SDMX_Structure.TextFormatType GetTextFormatType(XElement xmlElement)
        {
            SDMX_Structure.TextFormatType textFormatType = new SDMX_Structure.TextFormatType();

            if (xmlElement.Attribute("textType") != null)
            {
                if (xmlElement.Attribute("textType").Value != null)
                {
                    textFormatType.Texttype = GetTextTypeType(xmlElement.Attribute("textType").Value);
                }
            }

            if (xmlElement.Attribute("isSequence") != null)
            {
                if (xmlElement.Attribute("isSequence").Value != null)
                {
                    textFormatType.IsSequence = Convert.ToBoolean(xmlElement.Attribute("isSequence").Value);
                }
            }

            if (xmlElement.Attribute("minLength") != null)
            {
                if (xmlElement.Attribute("minLength").Value != null)
                {
                    textFormatType.Minlength = Convert.ToInt32(xmlElement.Attribute("minLength").Value);
                }
            }

            if (xmlElement.Attribute("maxLength") != null)
            {
                if (xmlElement.Attribute("maxLength").Value != null)
                {
                    textFormatType.Maxlength = Convert.ToInt32(xmlElement.Attribute("maxLength").Value);
                }
            }

            if (xmlElement.Attribute("startValue") != null)
            {
                if (xmlElement.Attribute("startValue").Value != null)
                {
                    textFormatType.Startvalue = Convert.ToDouble(xmlElement.Attribute("startValue").Value);
                }
            }

            if (xmlElement.Attribute("endValue") != null)
            {
                if (xmlElement.Attribute("endValue").Value != null)
                {
                    textFormatType.Endvalue = Convert.ToDouble(xmlElement.Attribute("endValue").Value);
                }
            }

            if (xmlElement.Attribute("interval") != null)
            {
                if (xmlElement.Attribute("interval").Value != null)
                {
                    textFormatType.Interval = Convert.ToDouble(xmlElement.Attribute("interval").Value);
                }
            }

            if (xmlElement.Attribute("duration") != null)
            {
                if (xmlElement.Attribute("duration").Value != null)
                {
                    textFormatType.Duration = xmlElement.Attribute("duration").Value;
                }
            }

            if (xmlElement.Attribute("decimals") != null)
            {
                if (xmlElement.Attribute("decimals").Value != null)
                {
                    textFormatType.Decimals = Convert.ToInt32(xmlElement.Attribute("decimals").Value);
                }
            }

            if (xmlElement.Attribute("pattern") != null)
            {
                if (xmlElement.Attribute("pattern").Value != null)
                {
                    textFormatType.Pattern = xmlElement.Attribute("pattern").Value;
                }
            }

            return textFormatType;
        }

        internal static SDMX_Common.IDType GetIDType(string idType)
        {
            SDMX_Common.IDType id = new SDMX_Common.IDType();

            if (!String.IsNullOrEmpty(idType))
            {
                id.Value = idType;
            }

            return id;
        }
    }
}
